/**
 * 
 */
package vwg.na.vwm.rh.modulo.pad;

import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.event.NodeSelectEvent;

import vwg.na.vwm.rh.modulo.pad.util.MontosPlaneacion;
import vwg.na.vwm.rh.modulo.pad.util.MovimientoPlaneacion;
import vwg.na.vwm.rh.modulo.pad.util.ProcesoPlaneacionPersonalAbstract;
import vwg.na.vwm.rh.motorsdk.commons.entidades.UnidadOrganizativa;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.entidadesgrales.PadCapturaEjercicio;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.entidadesgrales.PadDefinicionBudget;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.entidadesgrales.PadPPTipoMovimiento;

@ManagedBean
@SessionScoped
/**
 * @author Joel Ochoa [joel.ochoa@vw.com.mx]
 *
 */
public class PlaneacionPersonalMB extends ProcesoPlaneacionPersonalAbstract implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6358013106653611804L;
	
	private boolean panelPPShow;
	private boolean capturaEnabled;
	
	private List<MovimientoPlaneacion> movimientos;
	private List<PadPPTipoMovimiento> tiposMovimiento;
	private MontosPlaneacion totalForecast;
	private MontosPlaneacion totalBudget;
	private MontosPlaneacion totalDifBudgetForecast;
	
	private PadDefinicionBudget definicionBudget;
	private PadCapturaEjercicio capturaEjercicio;

	private String[][] meses = {{"1", "Enero"}, {"2", "Febrero"},
			{"3", "Marzo"}, {"4", "Abril"},
			{"5", "Mayo"}, {"6", "Junio"},
			{"7", "Julio"}, {"8", "Agosto"},
			{"9", "Septiembre"}, {"10", "Octubre"},
			{"11", "Noviembre"}, {"12", "Diciembre"}};

	@PostConstruct
	private void init(){
		
		tiposMovimiento = planeacionPersonalServicio.getTiposMovimiento();
		PadPPTipoMovimiento mov = new PadPPTipoMovimiento();
		mov.setTipoMovimiento(0);
		mov.setDescripcion("Eligir Movimiento");
		
		tiposMovimiento.add(0, mov);
		
		
		
		// Inicializacion de los nodos del componente Tree
		this.initNodes();
		
		// Se obtiene todas las sociedades activas
		sociedades = sociedadServicio.getAllActivos();
		
		capturaEjercicio = planeacionPersonalServicio.getCapturaEjercicio();
		
		sociedad = sociedades.get(0).getSociedad();
		
		// Se debe incializar lso movimientos que pudieran esta salvados
		movimientos = new ArrayList<MovimientoPlaneacion>();
		
		totalForecast = new MontosPlaneacion();
		totalDifBudgetForecast = new MontosPlaneacion();
		totalBudget = new MontosPlaneacion();
		
		processPlaneacionPersonal();
		
	}
	

	/**
	 * @return the meses
	 */
	public String[][] getMeses() {
		return meses;
	}

	public boolean isCapturaEnabled() {
		return capturaEnabled;
	}

	public List<MovimientoPlaneacion> getMovimientos() {
		return movimientos;
	}

	public void setMovimientos(List<MovimientoPlaneacion> movimientos) {
		this.movimientos = movimientos;
	}

	public List<PadPPTipoMovimiento> getTiposMovimiento() {
		return tiposMovimiento;
	}
	
	/**
	 * @return the totalForecast
	 */
	public MontosPlaneacion getTotalForecast() {
		return totalForecast;
	}

	public boolean isPanelPPShow() {
		return panelPPShow;
	}

	public void setPanelPPShow(boolean panelPPShow) {
		this.panelPPShow = panelPPShow;
	}


	/**
	 * @return the totalBudget
	 */
	public MontosPlaneacion getTotalBudget() {
		return totalBudget;
	}


	/**
	 * @return the totalDifBudgetForecast
	 */
	public MontosPlaneacion getTotalDifBudgetForecast() {
		return totalDifBudgetForecast;
	}


	/**
	 * @return the definicionBudget
	 */
	public PadDefinicionBudget getDefinicionBudget() {
		return definicionBudget;
	}
	
	/**
	 * @return the capturaEjercicio
	 */
	public PadCapturaEjercicio getCapturaEjercicio() {
		return capturaEjercicio;
	}


	@Override
	public void onNodeSelect(NodeSelectEvent event) {
		processPlaneacionPersonal();
	}

	@Override
	public void processChangeSociedad() {
		processPlaneacionPersonal();
	}
	
	private void processPlaneacionPersonal(){
		UnidadOrganizativa uo = (UnidadOrganizativa)this.selectedNode.getData();
		
		definicionBudget = this.planeacionPersonalServicio.getDefinicionBudget(
				uo.getUnidadOrganizativa(), sociedad, capturaEjercicio.getAnioCaptura());
		
		this.movimientos = new ArrayList<MovimientoPlaneacion>();
		
		// falta implementar obtener los movimientos
		
		
		if(definicionBudget != null){
			activateCapturaPanel(true);
			if(definicionBudget.getHabilitadoCaptura() == 1){
				capturaEnabled = true;
				loadMontosBudget(definicionBudget);
			}else{
				capturaEnabled = false;
			}
		}else{
			capturaEnabled = false;
			activateCapturaPanel(false);
		}
	}
	
	private void loadMontosBudget(PadDefinicionBudget def){
		
		BigDecimal total = new BigDecimal("0.00");
		
		totalBudget.setMontoEnero(def.getBudgetEnero());
		total = total.add(totalBudget.getMontoEnero());
		totalBudget.setMontoFebrero(def.getBudgetFebrero());
		total = total.add(totalBudget.getMontoFebrero());
		totalBudget.setMontoMarzo(def.getBudgetMarzo());
		total = total.add(totalBudget.getMontoMarzo());
		totalBudget.setMontoAbril(def.getBudgetAbril());
		total = total.add(totalBudget.getMontoAbril());
		totalBudget.setMontoMayo(def.getBudgetMayo());
		total = total.add(totalBudget.getMontoMayo());
		totalBudget.setMontoJunio(def.getBudgetJunio());
		total = total.add(totalBudget.getMontoJunio());
		totalBudget.setMontoJulio(def.getBudgetJulio());
		total = total.add(totalBudget.getMontoJulio());
		totalBudget.setMontoAgosto(def.getBudgetAgosto());
		total = total.add(totalBudget.getMontoAgosto());
		totalBudget.setMontoSeptiembre(def.getBudgetSeptiembre());
		total = total.add(totalBudget.getMontoSeptiembre());
		totalBudget.setMontoOctubre(def.getBudgetOctubre());
		total = total.add(totalBudget.getMontoOctubre());
		totalBudget.setMontoNoviembre(def.getBudgetNoviembre());
		total = total.add(totalBudget.getMontoNoviembre());
		totalBudget.setMontoDiciembre(def.getBudgetDiciembre());
		total = total.add(totalBudget.getMontoDiciembre());
		
		totalBudget.setMontoTotal(total);
		
		total = totalBudget.getMontoDiciembre().multiply(new BigDecimal("12"));
		totalBudget.setMontoNH(total);
	}
	
	public void addMovimiento(MovimientoPlaneacion movimiento){
		if(!movimientos.contains(movimiento)){
			//movimiento.setTipoMovimiento(tiposMovimiento.get(0));
			
			processMaximoIncremento(movimiento);
			processForecastSueldo(movimiento);
			movimientos.add(movimiento);
		}
	}
	
	public void deleteMovimiento(MovimientoPlaneacion movimiento){
		movimientos.remove(movimiento);
		processForecastTotales();
	}
	
	public void changeTipoMovimiento(MovimientoPlaneacion movimiento){
		
		movimiento.setIncremento(0);
		clearForecastSueldo(movimiento.getForecast());
		processForecastSueldo(movimiento);
		processMaximoIncremento(movimiento);
		
		// Si el movimiento es cambio de sociedad
		if(movimiento.getMovimiento() == 3){
			movimiento.setEnableIncremento(false);
		}else{
			movimiento.setEnableIncremento(true);
		}
	}
	
	private void processMaximoIncremento(MovimientoPlaneacion movimiento){
		switch (movimiento.getMovimiento()){
			case 1:
				movimiento.setMaximoIncremento(capturaEjercicio.getMaximoAumento());
				break;
			case 2:
				movimiento.setMaximoIncremento(capturaEjercicio.getMaximoPromocion());
				break;
			default:
				movimiento.setMaximoIncremento(0);
		}
		
	}
	
	public void changeMes(MovimientoPlaneacion movimiento){
		// Si el movimiento es distinto a cambio de sociedad
		if(movimiento.getMovimiento() != 3){
			processForecastSueldo(movimiento);
		}
		
	}
	
	public void changeIncremento(MovimientoPlaneacion movimiento){
		processForecastSueldo(movimiento);
	}
	
	private void processForecastTotales(){
		clearForecastSueldo(this.totalForecast);
		for(MovimientoPlaneacion movimiento : movimientos){
			this.totalForecast.setMontoEnero(
					this.totalForecast.getMontoEnero().add(
							movimiento.getForecast().getMontoEnero())); 
			this.totalForecast.setMontoFebrero(
					this.totalForecast.getMontoFebrero().add(
							movimiento.getForecast().getMontoFebrero()));
			this.totalForecast.setMontoMarzo(
					this.totalForecast.getMontoMarzo().add(
							movimiento.getForecast().getMontoMarzo())); 
			this.totalForecast.setMontoAbril(
					this.totalForecast.getMontoAbril().add(
							movimiento.getForecast().getMontoAbril()));
			this.totalForecast.setMontoMayo(
					this.totalForecast.getMontoMayo().add(
							movimiento.getForecast().getMontoMayo())); 
			this.totalForecast.setMontoJunio(
					this.totalForecast.getMontoJunio().add(
							movimiento.getForecast().getMontoJunio()));
			this.totalForecast.setMontoJulio(
					this.totalForecast.getMontoJulio().add(
							movimiento.getForecast().getMontoJulio())); 
			this.totalForecast.setMontoAgosto(
					this.totalForecast.getMontoAgosto().add(
							movimiento.getForecast().getMontoAgosto()));
			this.totalForecast.setMontoSeptiembre(
					this.totalForecast.getMontoSeptiembre().add(
							movimiento.getForecast().getMontoSeptiembre())); 
			this.totalForecast.setMontoOctubre(
					this.totalForecast.getMontoOctubre().add(
							movimiento.getForecast().getMontoOctubre()));
			this.totalForecast.setMontoNoviembre(
					this.totalForecast.getMontoNoviembre().add(
							movimiento.getForecast().getMontoNoviembre())); 
			this.totalForecast.setMontoDiciembre(
					this.totalForecast.getMontoDiciembre().add(
							movimiento.getForecast().getMontoDiciembre()));
			this.totalForecast.setMontoTotal(
					this.totalForecast.getMontoTotal().add(
							movimiento.getForecast().getMontoTotal()));
			this.totalForecast.setMontoNH(
					this.totalForecast.getMontoNH().add(
							movimiento.getForecast().getMontoNH()));
		}
		
		this.totalDifBudgetForecast.setMontoEnero(
				this.totalBudget.getMontoEnero().subtract(totalForecast.getMontoEnero()));
		this.totalDifBudgetForecast.setMontoFebrero(
				this.totalBudget.getMontoFebrero().subtract(totalForecast.getMontoFebrero()));
		this.totalDifBudgetForecast.setMontoMarzo(
				this.totalBudget.getMontoMarzo().subtract(totalForecast.getMontoMarzo()));
		this.totalDifBudgetForecast.setMontoAbril(
				this.totalBudget.getMontoAbril().subtract(totalForecast.getMontoAbril()));
		this.totalDifBudgetForecast.setMontoMayo(
				this.totalBudget.getMontoMayo().subtract(totalForecast.getMontoMayo()));
		this.totalDifBudgetForecast.setMontoJunio(
				this.totalBudget.getMontoJunio().subtract(totalForecast.getMontoJunio()));
		this.totalDifBudgetForecast.setMontoJulio(
				this.totalBudget.getMontoJulio().subtract(totalForecast.getMontoJulio()));
		this.totalDifBudgetForecast.setMontoAgosto(
				this.totalBudget.getMontoAgosto().subtract(totalForecast.getMontoAgosto()));
		this.totalDifBudgetForecast.setMontoSeptiembre(
				this.totalBudget.getMontoSeptiembre().subtract(totalForecast.getMontoSeptiembre()));
		this.totalDifBudgetForecast.setMontoOctubre(
				this.totalBudget.getMontoOctubre().subtract(totalForecast.getMontoOctubre()));
		this.totalDifBudgetForecast.setMontoNoviembre(
				this.totalBudget.getMontoNoviembre().subtract(totalForecast.getMontoNoviembre()));
		this.totalDifBudgetForecast.setMontoDiciembre(
				this.totalBudget.getMontoDiciembre().subtract(totalForecast.getMontoDiciembre()));
		this.totalDifBudgetForecast.setMontoTotal(
				this.totalBudget.getMontoTotal().subtract(totalForecast.getMontoTotal()));
		this.totalDifBudgetForecast.setMontoNH(
				this.totalBudget.getMontoNH().subtract(totalForecast.getMontoNH()));
	}
	
	private void processForecastSueldo(MovimientoPlaneacion movimiento){
		clearForecastSueldo(movimiento.getForecast());
		
		double factor = movimiento.getIncremento() / (double)100;
		
		BigDecimal[] forecastNuevo = new BigDecimal[12];
		
		BigDecimal nuevoSueldo = movimiento.getSueldo().multiply(new BigDecimal(factor));
		
		BigDecimal nuevoSueldoTotal = new BigDecimal("0.00");
		
		for(int i = 0; i < 12; i++){
			if(i >= (movimiento.getMes() - 1)){
				forecastNuevo[i] = nuevoSueldo;
				nuevoSueldoTotal = nuevoSueldoTotal.add(nuevoSueldo);
			}else{
				forecastNuevo[i] = new BigDecimal("0.00");
			}
		}
		
		movimiento.getForecast().setMontoEnero(forecastNuevo[0]);
		movimiento.getForecast().setMontoFebrero(forecastNuevo[1]);
		movimiento.getForecast().setMontoMarzo(forecastNuevo[2]);
		movimiento.getForecast().setMontoAbril(forecastNuevo[3]);
		movimiento.getForecast().setMontoMayo(forecastNuevo[4]);
		movimiento.getForecast().setMontoJunio(forecastNuevo[5]);
		movimiento.getForecast().setMontoJulio(forecastNuevo[6]);
		movimiento.getForecast().setMontoAgosto(forecastNuevo[7]);
		movimiento.getForecast().setMontoSeptiembre(forecastNuevo[8]);
		movimiento.getForecast().setMontoOctubre(forecastNuevo[9]);
		movimiento.getForecast().setMontoNoviembre(forecastNuevo[10]);
		movimiento.getForecast().setMontoDiciembre(forecastNuevo[11]);
		movimiento.getForecast().setMontoTotal(nuevoSueldoTotal);
		movimiento.getForecast().setMontoNH(
				forecastNuevo[11].multiply(new BigDecimal("12")));
		
		processForecastTotales();
	}
	
	private void clearForecastSueldo(MontosPlaneacion forecast){
		BigDecimal montoActualizado = new BigDecimal("0.00");
		forecast.setMontoEnero(montoActualizado);
		forecast.setMontoFebrero(montoActualizado);
		forecast.setMontoMarzo(montoActualizado);
		forecast.setMontoAbril(montoActualizado);
		forecast.setMontoMayo(montoActualizado);
		forecast.setMontoJunio(montoActualizado);
		forecast.setMontoJulio(montoActualizado);
		forecast.setMontoAgosto(montoActualizado);
		forecast.setMontoSeptiembre(montoActualizado);
		forecast.setMontoOctubre(montoActualizado);
		forecast.setMontoNoviembre(montoActualizado);
		forecast.setMontoDiciembre(montoActualizado);
		forecast.setMontoTotal(montoActualizado);
		forecast.setMontoNH(montoActualizado);
	}
	
	private void writeObject(java.io.ObjectOutputStream out)
		     throws IOException{
		out.defaultWriteObject();
	}
	
	private void readObject(java.io.ObjectInputStream in)
		     throws IOException, ClassNotFoundException{
		in.defaultReadObject();
	}
	
}
